#include "seqlist.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

//在结构体中套1级指针s
typedef struct _TagSeqList
{
        int length;
        int capacity;
        unsigned  int **node; //int* node[] //指针数组
}TagSeqList;

//创建并且返回一个空的线性表
SeqList* SeqList_Create(int capacity)
{
        TagSeqList *tmp = NULL;
        tmp = (TagSeqList *)malloc(sizeof(TagSeqList));
        if(tmp == NULL){
                printf("func SeqList_Create malloc failed! line 20 \n");
                return NULL;
        }
        memset(tmp, 0, sizeof(tmp));
        
        //根据capacity的大小分配节点的空间
        tmp->node = (unsigned int **)malloc(sizeof(unsigned int *)*capacity);
        if(tmp->node == NULL){
                printf("func SeqList_Create malloc failed! line 26 \n");
                free(tmp);
                return NULL;
        }
        tmp->capacity = capacity;
        tmp->length = 0;
        
        return  tmp;
}

//销毁一个线性表
void SeqList_Destroy(SeqList* list)
{
        TagSeqList *tlist = NULL;
        if(list == NULL){
                printf("func SeqList_Destroy list = null line 43 \n");
                return;
        }
        
        tlist = (TagSeqList *)list;
        if(tlist->node != NULL){
                free(tlist->node);
        }
        free(tlist);
}

//将一个线性表中的所有元素清空, 线性表回到创建时的初始状态
void SeqList_Clear(SeqList* list)
{
        TagSeqList *tlist = NULL;
        if(list == NULL){
                printf("func SeqList_Clear list = null line 59 \n");
                return;
        }
        tlist = (TagSeqList *)list;
        tlist->length = 0;
        return;
}

//返回一个线性表中的所有元素个数
int SeqList_Length(SeqList* list)
{
        TagSeqList *tlist = NULL;
        if(list == NULL){
                printf("func SeqList_Length list = null line 72 \n");
                return -1;
        }
        tlist = (TagSeqList *)list;
        return tlist->length;
}

int SeqList_Capacity(SeqList* list)
{
        TagSeqList *tlist = NULL;
        if(list == NULL){
                printf("func SeqList_Capacity list = null line 83 \n");
                return -1;
        }
        tlist = (TagSeqList *)list;
        return tlist->capacity;
}

//向一个线性表的pos位置处插入新元素node
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
        TagSeqList *tlist = NULL;
        int i = 0;

        if(list == NULL || node==NULL || pos < 0)
        {
                printf("func SeqList_Insert list == NULL || node==NULL || pos < 0 line 98 \n");
                return -1;
        }

        tlist = (TagSeqList *)list;
        
        //判断是不是满了
        if(tlist->length >= tlist->capacity){
                printf("func SeqList_Insert tlist->length >= tlist->capacity line 106 \n");
                return -1; 
        }

        //容错修正 6个长度 容量20; 用户pos10位置插入...
        if(pos >= tlist->length){
                pos = tlist->length; 
        }

        //1 元素后移
        for (i = tlist->length; i > pos; i--)
        {
                tlist->node[i] = tlist->node[i-1];        
        }
        
        //2 元素插入
        tlist->node[i] = node;
        tlist->length++;
        return 0;
}

//获取一个线性表的pos位置处的元素
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
        TagSeqList *tlist = NULL;

        if(list == NULL  || pos < 0)
        {
                printf("func SeqList_Get list == NULL  || pos < 0 line 134 \n");
                return NULL;
        }

        tlist = (TagSeqList *)list;

        return  (void *)tlist->node[pos];
}

//删除一个线性表的pos位置处的元素 返回值为被删除的元素, NULL表示删除失败
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
        int i = 0;
        TagSeqList *tlist = NULL;
        SeqListNode *tmp = NULL;

        if(list == NULL  || pos < 0)
        {
                printf("func SeqList_Delete list == NULL  || pos < 0 line 150 \n");
                return NULL;
        }
        tlist = (TagSeqList *)list;
        
        tmp = (SeqListNode *)tlist->node[pos]; //缓存pos的位置

        for (i = pos+1; i < tlist->length; i++) //pos位置后面的元素前移
        {
                tlist->node[i-1] = tlist->node[i];
        }
        tlist->length--;
        return  tmp;
}